package com.hibase.core.page.controller;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hibase.common.constant.ResponseCode;
import com.hibase.common.entity.ResponseModel;
import com.hibase.common.entity.User;
import com.hibase.common.util.EntityUtil;
import com.hibase.common.util.UserContext;
import com.hibase.core.page.constant.MenuConstant;
import com.hibase.core.page.entity.advance.AdvanceXmlVO;
import com.hibase.core.page.entity.advance.TabsLayout;
import com.hibase.core.page.entity.editxml.CardLayout;
import com.hibase.core.page.entity.editxml.EditXmlVO;
import com.hibase.core.page.entity.listxml.ListCustomSearchXmlVO;
import com.hibase.core.page.entity.listxml.ListQuickSearchXmlVO;
import com.hibase.core.page.entity.listxml.ListXmlVO;
import com.hibase.core.page.entity.menuxml.ItemMenuXmlVO;
import com.hibase.core.page.entity.menuxml.ItemXmlVO;
import com.hibase.core.page.entity.menuxml.MenuXmlVO;
import com.hibase.core.page.entity.pagemenuContent.PageMenuContent;
import com.hibase.core.page.entity.pageuserconfig.PageUserConfig;
import com.hibase.core.page.entity.pageuserconfig.vo.PageUserConfigViewVO;
import com.hibase.core.page.entity.window.WindowXmlVO;
import com.hibase.core.page.service.pagemenucontent.PageMenuContentService;
import com.hibase.core.page.service.pageuserconfig.PageUserConfigService;
import com.hibase.core.page.utils.PageConfigUtils;
import com.hibase.core.page.utils.XStreamUtils;
import com.hibase.core.web.annotation.HibaseRequestMapping;
import com.hibase.core.web.entity.OperationIdEntity;
import com.hibase.common.exception.HibaseAssert;
import com.hibase.upms.service.user.MdsUserService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * 描述:
 *
 * @author li-wei-hua
 * @date 2021-03-17 15:15
 */
@RequestMapping("pageConfig")
@Api("页面配置")
@RestController
@Slf4j
public class PageConfigController {

    @Autowired
    private PageMenuContentService pageMenuContentService;

    @Autowired
    private MdsUserService userService;
    
    @SuppressWarnings("unchecked")
	@ApiOperation(value = "获取菜单配置", httpMethod = "POST")
    @HibaseRequestMapping(value = "getMenuConfig")
	public ResponseModel<String> getMenuConfig() {
    	long startTime = System.currentTimeMillis();
		// 判断用户是否登录
    	User user = UserContext.get();
		if (user == null) {
			return ResponseModel.failMsg(ResponseCode.USER_NOTLOGIN.getCode(), ResponseCode.USER_NOTLOGIN.getMessage());
		}
		// step 1.读取XML
		List<MenuXmlVO> menuList = pageMenuContentService.selectAllMenusContent();
		log.info("getMenuConfig-------------------使用时间[1]：" + (System.currentTimeMillis() - startTime) + "----------------------");
		// step 2.TODO 权限过滤menus
		List<String> possessMenusList = userService.selectPossessMenusList();

		if (CollUtil.isEmpty(possessMenusList)) {
			return ResponseModel.failMsg(ResponseCode.USER_NO_PERMISSIONS.getCode(),
					ResponseCode.USER_NO_PERMISSIONS.getMessage());
		}
		
		List<MenuXmlVO> resultList = menuList.stream().filter(p -> possessMenusList.contains(p.getId())).peek(p -> {
			List<ItemMenuXmlVO> itemMenuList = p.getChildren().stream()
					.filter(c -> possessMenusList.contains(c.getId())).peek(c -> {
						List<ItemXmlVO> itemList = c.getItemList().stream()
								.filter(i -> possessMenusList.contains(i.getId())).collect(Collectors.toList());
						c.setItemList(itemList);
					}).collect(Collectors.toList());
			if (null != itemMenuList && itemMenuList.size() > 0) {
				p.setChildren(itemMenuList);
			}
		}).collect(Collectors.toList());
		log.info("getMenuConfig-------------------使用时间[3]：" + (System.currentTimeMillis() - startTime) + "----------------------");
		return ResponseModel.successMsg(resultList);
	}

    @SuppressWarnings("unchecked")
	@ApiOperation(value = "获取页面配置", httpMethod = "POST")
    @HibaseRequestMapping(value = "getListConfig")
    public ResponseModel<String> getListConfig(@RequestBody OperationIdEntity id) throws IOException {

        // step 1.读取XML
//        List<URL> menuURLS = ResourceUtil.getResources("pageConfig/menu");
        List<PageMenuContent> menuContentByName = pageMenuContentService.getMenuContentByName(id.getId());
        HibaseAssert.notEmpty(menuContentByName, "【{}】，配置文件被外星人偷走了", id.getId());

        PageMenuContent pageMenuContent = menuContentByName.get(0);
        if (pageMenuContent.getType().equals(MenuConstant.PageType.LIST)) {
            String xmlStr = XmlUtil.toStr(XmlUtil.readXML(pageMenuContent.getContent()));
            ListXmlVO listXmlVO = XStreamUtils.toBean(xmlStr, ListXmlVO.class);
            // step 2. 用Xstream 转为对应对象
            return ResponseModel.successMsg(this.disposeListXmlVO(listXmlVO));
        } else if (pageMenuContent.getType().equals(MenuConstant.PageType.EDIT)) {
            String xmlStr = XmlUtil.toStr(XmlUtil.readXML(pageMenuContent.getContent()));
            EditXmlVO editXmlVO = XStreamUtils.toBean(xmlStr, EditXmlVO.class);
            // step 2. 用Xstream 转为对应对象
            return ResponseModel.successMsg(this.disposeEditXmlVO(editXmlVO));
        } else if (pageMenuContent.getType().equals(MenuConstant.PageType.WINDOW)) {
            String xmlStr = XmlUtil.toStr(XmlUtil.readXML(pageMenuContent.getContent()));
            WindowXmlVO windowXmlVO = XStreamUtils.toBean(xmlStr, WindowXmlVO.class);
            // step 3. 用Xstream 转为对应对象
            return ResponseModel.successMsg(this.disposeWindowXmlVO(windowXmlVO));
        } else if (pageMenuContent.getType().equals(MenuConstant.PageType.ADVANCE)) {
            // 高级编辑-关联编辑
            String xmlStr = XmlUtil.toStr(XmlUtil.readXML(pageMenuContent.getContent()));
            AdvanceXmlVO uploadXmlVO = XStreamUtils.toBean(xmlStr, AdvanceXmlVO.class);
            // step 3. 用Xstream 转为对应对象
            return ResponseModel.successMsg(this.disposeAdvanceXmlVO(uploadXmlVO));
        }
        return null;

    }

    @Autowired
    private PageUserConfigService pageUserConfigService;

    private JSONObject disposeListXmlVO(ListXmlVO listXmlVO) {
    	
    	//通过语言判断是否登录
    	User loginUserInfo = UserContext.get();
    	HibaseAssert.notNull(loginUserInfo, ResponseCode.USER_NOTLOGIN.getMessage());

        // step 1. 处理查询控件
        if (listXmlVO.getListLayout().getCustomSearchs() != null) {
            List<ListCustomSearchXmlVO> customSearch = PageConfigUtils
                    .disposeListCustomSearch(listXmlVO.getListLayout().getCustomSearchs());
            listXmlVO.getListLayout().setCustomSearch(customSearch);
            listXmlVO.getListLayout().setCustomSearchs(null);
        }

        // step 2. 获取当前用户列表字段配置
        List<PageUserConfig> userList = pageUserConfigService.list(new QueryWrapper<PageUserConfig>()
                .eq("user_id", loginUserInfo.getId()).eq("menu_id", listXmlVO.getListLayout().getId()));
        listXmlVO.getListLayout().setUserConfig(EntityUtil.transformByJson(userList, PageUserConfigViewVO.class));
        // step 3. 处理按钮控件
        listXmlVO.getListLayout().setButtons(listXmlVO.getListLayout().getButton().getButtons());
        listXmlVO.getListLayout().setButton(null);

        // step 4. 处理按钮控件-params
        if (listXmlVO.getListLayout().getButtons() != null) {
            listXmlVO.getListLayout().getButtons().forEach(e -> {
                if (e.getParamList() != null && e.getParamList().getParam() != null && e.getParamList().getParam().size() > 0) {
                    e.setParams(e.getParamList().getParam());
                    e.setParamList(null);
                }
            });

        }
        listXmlVO.getListLayout().setButton(null);
        
        // step 5. 处理listField-fieldColor -- linkButton
        if (listXmlVO.getListLayout().getListField() != null) {
            listXmlVO.getListLayout().getListField().forEach(e -> {
                if (e.getFieldColor() != null && e.getFieldColor().getFieldColor() != null && e.getFieldColor().getFieldColor().size() > 0) {
                    e.setFieldColors(e.getFieldColor().getFieldColor());
                    e.setFieldColor(null);
                }
				if (StrUtil.isNotBlank(e.getPageId())) {
					HibaseAssert.isTrue(e.getType().equals("LINK"), "listField中配置pageId只能在type=\"LINK\"中");
				}
				if (StrUtil.isNotBlank(e.getPageIdRule())) {
					HibaseAssert.isTrue(e.getType().equals("LINK"), "listField中配置pageIdRule只能在type=\"LINK\"中");
				}
				if (e.getLinkButton() != null && e.getLinkButton().getLinkButton() != null && e.getLinkButton().getLinkButton().size() > 0) {
					e.setLinkButtons(e.getLinkButton().getLinkButton());
					e.setLinkButton(null);
				}
            });
        }
        listXmlVO.getListLayout().setButton(null);
        
        // step 6. 处理快速条件查询控件(quickSearch)-params
		if (listXmlVO.getListLayout().getQuickSearchs() != null) {
			ListQuickSearchXmlVO e = listXmlVO.getListLayout().getQuickSearchs();
			if (e.getParam() != null && e.getParam().getParam() != null && e.getParam().getParam().size() > 0) {
				e.setParams(e.getParam().getParam());
				e.setParam(null);
			}
		}

        return JSONUtil.parseObj(JSON.toJSONString(listXmlVO));
    }

    private JSONObject disposeEditXmlVO(EditXmlVO editXmlVO) {

        // step 1. 处理编辑控件
        List<CardLayout> cardLayouts = PageConfigUtils.disposeEditCardLayout(editXmlVO.getEditLayout().getCardLayout());
        editXmlVO.getEditLayout().setCardLayout(cardLayouts);

        // step 2. 处理按钮控件
        editXmlVO.getEditLayout().setButtons(editXmlVO.getEditLayout().getButton().getButtons());
        editXmlVO.getEditLayout().setButton(null);

        return JSONUtil.parseObj(JSON.toJSONString(editXmlVO));
    }

    /**
     * 解析 WindowXml
     *
     * @param windowXmlVO
     * @return
     */
    private JSONObject disposeWindowXmlVO(WindowXmlVO windowXmlVO) {
        windowXmlVO.getWindowLayout().setParams(windowXmlVO.getWindowLayout().getParam().getParam());
        windowXmlVO.getWindowLayout().setParam(null);
        ;
        return JSONUtil.parseObj(JSON.toJSONString(windowXmlVO));
    }

    /**
     * @param advanceXmlVO
     * @return
     * @Title: PageConfigController
     * @Description: advanceXmlVO
     * @author TimBrian
     * @since May 19, 2021 10:36:12 AM
     */
    private JSONObject disposeAdvanceXmlVO(AdvanceXmlVO advanceXmlVO) {

        if (null != advanceXmlVO.getAdvaneceLayout().getDetail().getCardLayout() && advanceXmlVO.getAdvaneceLayout().getDetail().getCardLayout().size() > 0) {
            advanceXmlVO.getAdvaneceLayout().getDetail().getCardLayout().stream().forEach(e -> {
            	
            	if(ObjectUtil.isNotEmpty(e.getListLayout().getCustomSearchs())) {
	                // step 1. 处理编辑控件
	                List<ListCustomSearchXmlVO> customSearch = PageConfigUtils.disposeListCustomSearch(e.getListLayout().getCustomSearchs());
	                e.getListLayout().setCustomSearch(customSearch);
	                e.getListLayout().setCustomSearchs(null);
            	}
                // step 2 处理 detail 按钮控件 -- 处理params
                e.getListLayout().getButton().getButtons().forEach(b -> {
                    if (b.getParamList() != null && b.getParamList().getParam() != null && b.getParamList().getParam().size() > 0) {
                        b.setParams(b.getParamList().getParam());
                        b.setParamList(null);
                    }
                });
                e.getListLayout().setButtons(e.getListLayout().getButton().getButtons());
                e.getListLayout().setButton(null);
                
                // step 1.3 处理listField-fieldColor
                if (e.getListLayout().getListField() != null) {
                    e.getListLayout().getListField().forEach(p -> {
                        if (p.getFieldColor() != null && p.getFieldColor().getFieldColor() != null && p.getFieldColor().getFieldColor().size() > 0) {
                            p.setFieldColors(p.getFieldColor().getFieldColor());
                            p.setFieldColor(null);
                        }
                    });
                }
            });
        }

        // step 3. 处理 main 编辑按钮
        if (null != advanceXmlVO.getAdvaneceLayout().getMain().getCardLayout() && advanceXmlVO.getAdvaneceLayout().getMain().getCardLayout().size() > 0) {
            List<CardLayout> cardLayouts = PageConfigUtils.disposeEditCardLayout(advanceXmlVO.getAdvaneceLayout().getMain().getCardLayout());
            advanceXmlVO.getAdvaneceLayout().getMain().setCardLayout(cardLayouts);
        }

        // step 4. 处理 main 按钮控件
        advanceXmlVO.getAdvaneceLayout().getMain().setButtons(advanceXmlVO.getAdvaneceLayout().getMain().getButton().getButtons());
        advanceXmlVO.getAdvaneceLayout().getMain().setButton(null);

        // step 5. 处理 detail tabsLayout 编辑按钮
        if (null != advanceXmlVO.getAdvaneceLayout().getDetail().getTabsLayout() && advanceXmlVO.getAdvaneceLayout().getDetail().getTabsLayout().size() > 0) {
            List<TabsLayout> detailTabsLayouts = PageConfigUtils.disposeTabsCardLayout(advanceXmlVO.getAdvaneceLayout().getDetail().getTabsLayout());
            advanceXmlVO.getAdvaneceLayout().getDetail().setTabsLayout(detailTabsLayouts);
        }

        // step 6 处理 main tabsLayout 编辑按钮
        if (null != advanceXmlVO.getAdvaneceLayout().getMain().getTabsLayout() && advanceXmlVO.getAdvaneceLayout().getMain().getTabsLayout().size() > 0) {
            List<TabsLayout> mainTabsLayouts = PageConfigUtils.disposeTabsCardLayout(advanceXmlVO.getAdvaneceLayout().getMain().getTabsLayout());
            advanceXmlVO.getAdvaneceLayout().getMain().setTabsLayout(mainTabsLayouts);
        }

        return JSONUtil.parseObj(JSON.toJSONString(advanceXmlVO));
    }

}
